package ru.andrew.jclazz.gui;

import java.awt.event.*;
import javax.swing.filechooser.FileFilter;
import java.io.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
import ru.andrew.jclazz.*;
import ru.andrew.jclazz.core.Clazz;
import ru.andrew.jclazz.core.ClazzException;

public class MainForm extends JFrame implements ActionListener, TreeSelectionListener
{
    private static final String A_EXIT = "EXIT";
    private static final String A_OPEN = "OPEN";
    private static final String A_DECOMPILE = "DECOMPILE";

    private Clazz clazz;
    private File lastOpenedDirectory = null;

    public MainForm()
    {
        initComponents();

        // TODO review
        tree.addTreeSelectionListener(this);
        tree.setCellRenderer(new ClazzTreeNodeCellRenderer());
        tree.setModel(new DefaultTreeModel(null));
        setContentPane(mainPanel);
    }

    // TreeSelectionListener implementation

    public void valueChanged(TreeSelectionEvent tse)
    {
        ClazzTreeNode node = (ClazzTreeNode) tse.getPath().getLastPathComponent();
        textPane.setText(node.getDescription());
    }

    // Action Listener implementation

    public void actionPerformed(ActionEvent e)
    {
        String cmd = e.getActionCommand();
        if (A_EXIT.equals(cmd))
        {
            System.exit(0);
        }
        else if (A_OPEN.equals(cmd))
        {
            openClass();
        }
        else if (A_DECOMPILE.equals(cmd))
        {
            openDecompileWindow();
        }
    }

    protected void openClass()
    {
        JFileChooser chooser = new JFileChooser();
        chooser.setFileFilter(new FileFilter() {

            public boolean accept(File pathname)
            {
                return pathname.getName().endsWith(".class") || pathname.isDirectory();
            }

            public String getDescription()
            {
                return "Java class files";
            }
        });
        if (lastOpenedDirectory != null)
        {
            chooser.setCurrentDirectory(lastOpenedDirectory);
        }

        int returnVal = chooser.showOpenDialog(this);
        if(returnVal != JFileChooser.APPROVE_OPTION)
        {
            JOptionPane.showMessageDialog(this, "No class selected", "Exiting...", JOptionPane.WARNING_MESSAGE);
            return;
        }
        try
        {
            lastOpenedDirectory = chooser.getSelectedFile().getParentFile();
            this.clazz = new Clazz(chooser.getSelectedFile().getAbsolutePath());
        }
        catch (ClazzException ce)
        {
            JOptionPane.showMessageDialog(this, ce.toString(), "Clazz Exception", JOptionPane.ERROR_MESSAGE);
            System.exit(1);
        }
        catch (IOException ioe)
        {
            JOptionPane.showMessageDialog(this, ioe.toString(), "Input/Output Exception", JOptionPane.ERROR_MESSAGE);
            System.exit(1);
        }

        setTitle(clazz.getThisClassInfo().getFullyQualifiedName());
        decompileMenuItem.setEnabled(true);
        tree.setModel(new ClazzTreeUI(this.clazz).getTreeModel());
        tree.setSelectionRow(0);
        pack();
    }

    protected void openDecompileWindow()
    {
        DecompileForm decompileForm = new DecompileForm();
        try
        {
            decompileForm.setClazz(this.clazz);
        }
        catch (IllegalArgumentException iae)
        {
            // Error occured, won't display decompile form
            return;
        }
        decompileForm.setModal(true);
        decompileForm.setSize(1000, 500);
        decompileForm.setVisible(true);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        mainPanel = new javax.swing.JPanel();
        splitPanel = new javax.swing.JSplitPane();
        jScrollPane1 = new javax.swing.JScrollPane();
        tree = new javax.swing.JTree();
        jScrollPane3 = new javax.swing.JScrollPane();
        textPane = new javax.swing.JTextPane();
        menuBar = new javax.swing.JMenuBar();
        fileMenu = new javax.swing.JMenu();
        openMenuItem = new javax.swing.JMenuItem();
        fileSeparator = new javax.swing.JSeparator();
        exitMenuItem = new javax.swing.JMenuItem();
        operationsMenu = new javax.swing.JMenu();
        decompileMenuItem = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("jclazz");
        setName("mainFrame"); // NOI18N
        getContentPane().setLayout(new javax.swing.BoxLayout(getContentPane(), javax.swing.BoxLayout.LINE_AXIS));

        mainPanel.setPreferredSize(new java.awt.Dimension(600, 400));
        mainPanel.setLayout(new java.awt.GridBagLayout());

        splitPanel.setDividerLocation(250);

        jScrollPane1.setViewportView(tree);

        splitPanel.setLeftComponent(jScrollPane1);

        textPane.setContentType("text/html");
        textPane.setEditable(false);
        jScrollPane3.setViewportView(textPane);

        splitPanel.setRightComponent(jScrollPane3);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        mainPanel.add(splitPanel, gridBagConstraints);

        getContentPane().add(mainPanel);

        fileMenu.setText("File");

        openMenuItem.setText("Open");
        openMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                openMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(openMenuItem);
        fileMenu.add(fileSeparator);

        exitMenuItem.setText("Exit");
        exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exitMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(exitMenuItem);

        menuBar.add(fileMenu);

        operationsMenu.setText("Operations");

        decompileMenuItem.setText("Decompile");
        decompileMenuItem.setEnabled(false);
        decompileMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                decompileMenuItemActionPerformed(evt);
            }
        });
        operationsMenu.add(decompileMenuItem);

        menuBar.add(operationsMenu);

        setJMenuBar(menuBar);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_exitMenuItemActionPerformed
    {//GEN-HEADEREND:event_exitMenuItemActionPerformed
        System.exit(0);
    }//GEN-LAST:event_exitMenuItemActionPerformed

    private void openMenuItemActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_openMenuItemActionPerformed
    {//GEN-HEADEREND:event_openMenuItemActionPerformed
        openClass();
    }//GEN-LAST:event_openMenuItemActionPerformed

    private void decompileMenuItemActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_decompileMenuItemActionPerformed
    {//GEN-HEADEREND:event_decompileMenuItemActionPerformed
        openDecompileWindow();
    }//GEN-LAST:event_decompileMenuItemActionPerformed

    public static void main(String args[])
    {
        java.awt.EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                try
                {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
                MainForm mf = new MainForm();
                mf.setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem decompileMenuItem;
    private javax.swing.JMenuItem exitMenuItem;
    private javax.swing.JMenu fileMenu;
    private javax.swing.JSeparator fileSeparator;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JPanel mainPanel;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JMenuItem openMenuItem;
    private javax.swing.JMenu operationsMenu;
    private javax.swing.JSplitPane splitPanel;
    private javax.swing.JTextPane textPane;
    private javax.swing.JTree tree;
    // End of variables declaration//GEN-END:variables

}
